<?php
/**
 * Nordic Repository
 * 
 * LICENSE
 * 
 * The new BSD license is applied on this source-file. For further
 * information please visit http://license.nordic-dev.de/newbsd.txt
 * or send an email to andre.moelle@gmail.com.
 */

/**
 * Necessary includes.
 */
Zend_Loader::loadClass('Zend_Db_Table_Row_Abstract');

/**
 * This class enables the row-objects to validate theirselves.
 * 
 * It provides two hooks (_post- and _preValidate) to make the data
 * ready for validating. The validate-method has to be implemented for
 * each row.
 * Additionally the algorithm to decide whether an update or an insert
 * will be tried differs to the default-implementation.
 * 
 * @category   Nordic
 * @package    Nordic_Db
 * @copyright  2007 Nordic Development
 * @license    http://license.nordic-dev.de/newbsd.txt (New-BSD license)
 * @author     Andre Moelle <andre.moelle@gmail.com>
 * @version    $Id: Row.php 3 2007-07-08 09:21:42Z andre.moelle $
 */
abstract class Nordic_Db_Row extends Zend_Db_Table_Row_Abstract
{
	/**
	 * Hook which is used after validating content.
	 * 
	 * @param void
	 * @return void
	 */
	protected function _postValidate ()
	{
		;
	}
	
	/**
	 * Hook which is called before validating the content.
	 * 
	 * @param void
	 * @return void
	 */
	protected function _preValidate ()
	{
		;
	}
	
	/**
	 * Sets the validating up. I.e. that the clean-data array is created.
	 * 
	 * This is necessary to get this implementation running.
	 * 
	 * @param void
	 * @return void
	 */
	protected function _setUpValidating ()
	{
		if($this->_cleanData == array())
		{
			$info = $this->getTable()->info();
			$this->_cleanData = array_flip($info[Zend_Db_Table_Abstract::COLS]);
			
			foreach($this->_cleanData as $key => $value)
			{
				$this->_cleanData[$key] = null;
			}
			
			foreach($this->_getPrimaryKey() as $key => $value)
			{
				$this->_cleanData[$key] = $value;
			}
		}
	}
	
	/**
	 * This method saves the content using the parent save-method.
	 * 
	 * To ensure that the input is clean, the input is validated before
	 * saving. Thereafter the input is declared as clean, since there
	 * were not any errors, because no exception was thrown. In some
	 * cases it is necessary to do some operations to get the validation
	 * working correctly. Thus there are two hooks defined:
	 * _preValidate and _postValidate. These hooks are called before and
	 * after validating the content. 
	 * 
	 * @param void
	 * @return void
	 * @throws Zend_Validate_Exception
	 */
	final public function save ()
	{
		$this->_preValidate();
		$this->validate();
		$this->_postValidate();
		
		$this->_setUpValidating();
		
		foreach($this->_getPrimaryKey() as $key => $value)
		{
			if(!$value)
			{
				try
				{
					return $this->_doInsert();
				}
				catch (Exception $e)
				{
					;
				}
			}
		}
		
		return $this->_doUpdate();
	}
	
	/**
	 * Adds functionality providing better use with input-array.
	 * 
	 * Elements which do not exist in the row, are not set. Result
	 * is an integer implying how many elements were set.
	 * 
	 * @return integer
	 * @see Zend_Db_Table_Row_Abstract::setFromArray()
	 */
	public function setFromArray (array $array)
	{
		$result = 0;
		
		foreach($array as $key => $value)
		{
			if(!isset($this->$key))
			{
				continue;
			}
			
			$this->$key = $value;
			$result++;
		}
		
		return $result;
	}
	
	/**
	 * Validates the content.
	 * 
	 * This method is used to assure that the incoming content is
	 * validated before getting into the database.
	 * 
	 * @throws Zend_Validate_Exception
	 */
	abstract public function validate ();
}
?>